/**
**
**       变色龙android端插件管理工具
**
**/

var fs = require('fs'),
	path = require('path'),
	shell = require('shelljs'),
	Q       = require('q'),
	exec = require('child_process').exec;
	//processor = require('processor');
var Project,
	ConfigXml,	  	//config.xml
	CodeSign,     	//唯一标识,用来防止插件冲突
	_Plugin,		//插件路径
	WWW,		  	//插件资源
	PkgName,	  	//插件包名
	PluginName;		//插件名

/**
*递归创建目录
*@dirname 目录路径
*@mode 模式
**/
var mkdirsSync = function (dirname, mode){
    if(fs.existsSync(dirname)){
        return true;
    }else{
        if(mkdirsSync(path.dirname(dirname), mode)){
            fs.mkdirSync(dirname, mode);
            return true;
        }
    }
}

function init(project) {
	Project = project;
	ConfigXml = path.join(Project,'res','xml','config.xml');
	//_Plugin = path.join(Project,'com','foss','user','plugin',codeSign);
    WWW = path.join(Project,'assets','www');
}

function zip(infile,outfile,callback) {
	var cmd = "zip -r " + outfile + " " + infile + '/*';
	exec(cmd, {maxBuffer: 10*1024*1024}, function(err, stdout, stderr) {
		if(callback && !err) {
        	callback();
        }
      });


}

function unzip(infile,outdir,callback) {
    
    var cmd = "unzip -o -d " + outdir + " " + infile ;
    console.log("cmd-->" + cmd);
    exec(cmd, {maxBuffer: 10*1024*1024}, function(err, stdout, stderr) {
        if(callback && !err) {
        	callback();
        }
      });
}

/**
** 在config.xml中增删插件信息
** @param pluginName 插件名
** @param pluginPkgname 插件包名
** @param addOrRemove true 增加 false 删除
**/
var setPluginInfo2Config  = function(project,pluginName,pluginPkgname,addOrRemove) {
	var content = ""+fs.readFileSync(path.join(project,'res','xml','config.xml'));
	var idxStart,idxEnd;
	idxStart = content.indexOf(pluginName);
	if(idxStart != -1 && !addOrRemove) { //删除
		var tmp = content.substring(0,idxStart);
		var idx = tmp.lastIndexOf('\n');
		tmp = content.substring(idx,content.length);
		idxEnd = tmp.indexOf("</feature>") + "</feature>".length;
		tmp = tmp.substring(0,idxEnd);
		content = content.replace(tmp,"");
	} else if(idxStart == -1 && addOrRemove){ //添加
		var info = "\t<feature name=\"" + pluginName + "\">\n"
        			+	"\t\t<param name=\"android-package\" value=\"" + pluginPkgname + "." + pluginName + "\"/>\n"
    				+ "\t</feature>\n";
        idxEnd = content.indexOf("</widget>");
        content = content.substring(0,idxEnd);
    	content += info;
    	content += "</widget>";
	} else {}

	fs.writeFileSync(ConfigXml,content,'utf-8');
}

/**
**   添加插件
**   @param pluginFile 插件zip包路径
**   拷贝到临时目录，解压，将相应文件拷到工程对应目录，修改config.xml,记录插件信息，删除临时文件
**/
function addPlugin(project,pluginFile) {
	init(project);
	//copyFile2TempDir(pluginFile);
	//var plugin = path.resolve("./tmp/" + path.basename(pluginFile,'.zip'));
	//unzip('./tmp/'+path.basename(pluginFile),'./tmp/',function() {
		copyWWW2TempDir(path.join(WWW,'www.zip'));
		unzip('www.zip','.',function() {
			var filePaths = scanAndMovePluginFile(pluginFile);
			//addPluginInfos('' + path.resolve('tmp/' + path.basename(pluginFile,'.zip') + '/config.json'),filePaths);
			addPluginInfos(path.join(pluginFile,'config.json'),filePaths);
			setPluginInfo2Config(project,PluginName,PkgName,true);
			zip('www','www.zip',function(){
				shell.mv('-f','www.zip',path.join(WWW));
				shell.rm('-f','www.zip');
				shell.rm('-r','www');
				//shell.rm('-r','tmp');
				//shell.rm('-r','__MACOSX');
			});
		});
		
	//});
	
	
	
}

/**
**   删除插件
**   @param pluginPkgname 插件包名
**   @param  pluginName 插件名
**/
function removePlugin(project,pluginPkgname,pluginName) {
	init(project);
	var conf = pluginPkgname.replace(/\./g,'_') + '_'+ pluginName + '.json';
	var pluginConf = path.join(project,'pluginConf',conf);
	if(fs.existsSync(pluginConf)) {
		var files = [],confJson,confObj,jsFiles = [];
		confJson = fs.readFileSync(pluginConf);
		confObj = JSON.parse(confJson);
		files = confObj.files.split(',');
		for(var i = 0; i < files.length;i++) {
			if(files[i].indexOf('.js') != -1) {
				jsFiles.push(files[i]);
			} else {
				console.log('delete ' + files[i] + 'from src');
				shell.rm('-f',files[i]);
			}
		}
		if(jsFiles.length > 0) {
			//zip -d test2.zip test2/ln.log 无法用
			copyWWW2TempDir(path.join(WWW,'www.zip'));
			unzip('www.zip','.',function() {
				shell.rm('-f','www.zip');
				shell.rm('-r','__MACOSX');
				for(var i = 0; i < jsFiles.length;i++) {
					console.log("delete " + jsFiles[i] + "from www");
					shell.rm('-f','www/js/' + jsFiles[i]);
				}
				zip('www','www.zip',function(){
					shell.mv('-f','www.zip',path.join(WWW));
					shell.rm('-f','www.zip');
					shell.rm('-r','www');
					shell.rm('-r','__MACOSX');
				});
			});
		}
		setPluginInfo2Config(project,pluginName,pluginPkgname,false);
		shell.rm('-f',pluginConf);
	}
}


/**
** 记录插件信息
** pluginPkgname  插件包名
** filePath  插件相关的所有文件
**/
function addPluginInfos(configFile,filePaths) {
	var json = "{\n";
	json += "\"status\":\"installed\",\n";
	json += "\"packgename\":" + "\"" + PkgName + "\",\n";
	json += "\"name\":" + "\"" + PluginName + "\",\n";
	var files = "";
	for(var i = 0; i < filePaths.length;i++) {
		files += filePaths[i];
		if(i != filePaths.length - 1) {
			files += ",";
		}	
	}
	json += "\"files\":" + "\"" + files + "\"\n";
	json += "}";
	var pluginConf = path.join(Project,'pluginConf',PkgName.replace(/\./g,'_') + "_" + PluginName+ '.json');
	if(!fs.existsSync(pluginConf)) {
		mkdirsSync(path.dirname(pluginConf));
	}
	fs.writeFileSync(pluginConf,json);
}



function copyFile2TempDir(pluginFile) {
	if(fs.existsSync(pluginFile)) {
		shell.cp('-r', pluginFile, './tmp/');
		return true;
	}
	return false;
}

function copyWWW2TempDir(www) {
if(fs.existsSync(www)) {
		shell.cp('-r', www, '.');
		return true;
	}
	return false;
}


function isInstalled(pluginPkgname) {
	var pluginConf = path.join(Project,'pluginConf',pluginPkgname.replace(/\./g,'_') + '.json');
	var conf = fs.readFileSync(pluginConf);
}

/**
**    扫描并移动插件
**/
function scanAndMovePluginFile(pluginDir) {
  
  //递归扫描文件
  var fileDirs = [];
  var confJson = "" + fs.readFileSync(path.join(pluginDir,'config.json'));
  var confObj = JSON.parse(confJson);
  PkgName = confObj.package;
  PluginName = confObj.name;
  var dstPath;
  var walk = function(dir) {
    var files = fs.readdirSync(dir);
    files.forEach(function(item) {
      var tmpPath = path.join(dir,item);
      var stats = fs.statSync(tmpPath);
      if(stats.isDirectory()) {
        walk(tmpPath);
      } else {
      		console.log("扫描文件.......:" + tmpPath);
          if(tmpPath.indexOf('.java') != -1 || tmpPath.indexOf('.js') != -1) {
          		if(tmpPath.indexOf('.java') != -1) {
          			moveJavaFileToSuitPath(tmpPath);
          			dstPath =  (confObj.package).replace(/\./g,'/');
          			var p = getJavaFilePackgePath(tmpPath);
          			dstPath = path.join(Project,'src',p,item);
          			fileDirs.push(dstPath);
          		} else if(tmpPath.indexOf('.js') != -1 && tmpPath.indexOf('.json') == -1){
          			moveJsFileToSuitPath(tmpPath);
          			fileDirs.push(item);
          		} else {
          			if(tmpPath.indexOf('config.json') == -1) {
          				moveJsonFileToSuitPath(tmpPath);
          				fileDirs.push(path.join(Project,'pluginConf',item));
          			}
          			
          		}
          } 
        }
      });
    }

    walk(pluginDir);
    return fileDirs;
}

/**
** 获取java文件的包路径
**
**/
function getJavaFilePackgePath(javaFile) {
	var javaBuffer = fs.readFileSync(javaFile,'utf-8');
	if(javaBuffer != null) {
		var idxStart,idxEnd,pkgname;
		idxStart = javaBuffer.indexOf('packge') + 'package'.length + 1;
		idxEnd = javaBuffer.indexOf(';');
		pkgname = javaBuffer.substring(idxStart,idxEnd);
		pkgname = pkgname.replace(/(^\s*)|(\s*$)/g, "")
		return pkgname.replace(/\./g,'/');
	}
}

/**
**    将java文件移动到相应的包中去
**/
function moveJavaFileToSuitPath(javaFile) {
	if(fs.existsSync(javaFile)) {
		var javapath = getJavaFilePackgePath(javaFile);
		if(javapath != null && javapath != "") {
			var movePath = path.join(Project,'src',javapath);
			if(!fs.existsSync(movePath)) {
				shell.mkdir('-p', movePath);
			}

			shell.cp('-f', javaFile, movePath);
		}
	}
}

/**
**    将js文件移动到相应的包中去
**/
function moveJsFileToSuitPath(jsFile) {
  if(fs.existsSync(jsFile)) {
  	var jsPath = path.resolve("www/js");
  	if(jsPath != null && jsPath != "") {
  		shell.cp('-f',jsFile,jsPath);
  	}
  }
}

/**
**    将json文件移动到相应的包中去
**/
function moveJsonFileToSuitPath(jsonFile) {
	if(fs.existsSync(jsonFile)) {
		var movePath = path.join(Project,'pluginConf');
		if(!fs.existsSync(movePath)) {
			shell.mkdir('-p', movePath);
		}
		shell.cp('-f', jsonFile, movePath);
	}
}
/**
** 获取相对路径
**@param fullPath 全路径
**@param startPath 起始路径
** return fullPath - startPath的路径
**/
function getReleativePath(fullPath,startPath) {
	if(isVaildString(fullPath) && isVaildString(startPath)) {
		if(fullPath.indexOf(startPath) != -1) {
			return fullPath.replace(startPath,"");
		}
		
	}
	return "";
}

/**
**  是否有效字符串
**  @param str 输入字符串
**/
function isVaildString(str) {

	if(str == null || str == "") {
		return false;
	}
	return true;
}

/**
* 获取指定参数的值
* @param option 输入参数
* @param param  提取的参数名
*/
var extractParamValue = function(option,param) {
  var value = "";
  if(option.indexOf(param) !=-1) {
    var start = option.indexOf('=') + 1;
    value = option.substring(start);
  }
  return value;
}

/**
*获取参数名
* @param option 输入参数
*/

var extractParamName = function(option) {
  var start = option.indexOf('=');
  var selector = option.substring(0,start);
  return selector;
}

module.exports.run = function(options) {
	if (typeof options == "string") options = [options];
	var op = {
        opType: '',
        project: '',
        packname: '',
        name:'',
        file:'',

    };
	for (var i=0; options && (i < options.length); ++i) {
        if (/^--/.exec(options[i])) {
            var option = options[i].substring(2);
            var selector = extractParamName(option);
            switch(selector) {
            	case 'project':
            		var prj = extractParamValue(option,"project");
            		op.project = prj;
            	break;
            	case 'operateType':
            		var opType = extractParamValue(option,"operateType");
            		op.opType = opType;
            	break;
            	case 'package':
            		var packname = extractParamValue(option,"package");
            		op.packname = packname;
            	break;
            	case 'name':
            		var name = extractParamValue(option,"name");
            		op.name = name;
            	break;
            	case 'file':
            		var file = extractParamValue(option,"file");
            		op.file = file;
            	break;
            }
        } else {
            return Q.reject('operate option \'' + options[i] + '\' not recognized.');
        }
    }

    if(op.opType == '') {
    	return Q.reject('you must set operateType.');
    }
    if(op.project == '') {
    		return Q.reject('you must set project.');
    }

    if(op.opType == 'add') {
    	if(op.file == '') {
    		return Q.reject('you must set file.');
    	} 
    	addPlugin(op.project,op.file);
    } else if(op.opType == 'remove'){
    	if(op.packname == '') {
    		return Q.reject('you must set packname.');
    	}
    	if(op.name == '') {
    		return Q.reject('you must set name.');
    	}

    	removePlugin(op.project,op.packname,op.name);
    }
}

module.exports.help = function() {
    console.log('Usage: ' + ' Chameleon v2 for android PluginManager');
    console.log('Build Types : ');
    console.log('    \'--operateType=\': add or remove the plugin to chameleon v2 of android(从变色龙v2 android工程中安装或删除插件) [required value = add or remove]');
    console.log('    \'--project=\': the project of chameleon project for android (变色龙v2 android项目路径) [required]');
    console.log('    \'--package=\': plugin package name(插件包名)  [required for remove]');
    console.log('    \'--name=\': plugin name(插件名)  [required for remove]');
    console.log('    \'--file=\': plugin file path(插件zip包路径) [require for add]');
    process.exit(0);
};



/////////test/////////////////////

//var relPath = getReleativePath("/Users/zhouzhineng/Desktop/chameleon-eclipse/lib","/Users/zhouzhineng/Desktop");
//console.log("相对路径:---->" + relPath);

//var project = "/Users/zhouzhineng/Desktop/chamleon-android-demo/test_project";
//var filePaths = ['/Users/zhouzhineng/Desktop/file1','/User/zhouzhineng/Desktop/file2','/Users/zhouzhineng/Desktop/file3'];
//addPluginInfos('com.foss.user.plugin.jnet',filePaths);
//removePluginInfo('com.foss.user.plugin.jnet');
//var basename = path.basename("/Users/zhouzhineng/Desktop/build_eclipse/lib/tmp/www.zip");
//console.log('basename---->'+basename);
//addPlugin(project,'/Users/zhouzhineng/Desktop/chamleon-android-demo/plugin.zip');
//removePlugin(project,'com.foss.user.plugin.jnet','MyPlugin');

